﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CaroClient
{
    public enum Mode
    {
        Host,
        Client,
        Computer
    }

    public partial class frmPlay : Form
    {
        #region Biến

        Mode mode;//Chế độ của người chơi. Tạo phòng hay tham gia phòng
        //Biến của của chế độ tạo phòng
        private Socket server;
        private Socket clientOfServer;
        //Biến của chế độ tham giao phòng chơi
        TcpClient tcpClientConnectToServer;
        private string ip;
        int port = 100;
        //Biến gửi nhận dữ liệu giữa 2 máy
        byte[] dataRecive, dataSend;
        private Thread thKetNoiDenServer, thListen, thStartGame;
        #endregion

        #region Khởi tạo

        //Chế độ tạo phòng
        public frmPlay()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
            this.CreateHost();
            this.Text = "Đợi  người chơi...";
            this.boardUI1.AllowPlay = false;
        }

        public frmPlay(Mode m)
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
            this.boardUI1.AllowPlay = true;
            if (m == Mode.Computer)
            {
                this.boardUI1.MouseClick -= boardUI1_MouseClick;
                this.boardUI1.MouseClick += boardUI1_MouseClick_Ai;
                this.btnConnect.Visible = false;
                this.btnCreateHost.Visible = false;
            }
        }

        //Chế độ tham gia phòng
        public frmPlay(string ipserver)
        {
            InitializeComponent();
            this.ip = ipserver;
            this.ConnectToHost();
        }

        #endregion

        private void SloveData(string[] data)
        {
            if (data[0] == "Board")
            {
                this.boardUI1.Fuck(Convert.ToInt32(data[1]), Convert.ToInt32(data[2]), data[3][0]);
                this.boardUI1.AllowPlay = true;//Người ta chơi xong đến lượt mình
            }
            if (data[0] == "name")
            {
                this.Text = Global.Player.Name + " vs " + data[1];
            }
            if (data[0] == "Data")
            {
                if (data[1] == "Close")
                {
                    MessageBox.Show("Đối thủ đã thoát");
                    this.Close();
                }
            }
        }

        #region Chế độ tạo phòng

        //Nhận kết nối
        private void Listen()
        {
            this.mode = Mode.Host;
            try
            {
                this.server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //IPEndPoint iep = new IPEndPoint(IPAddress.Parse(this.ip), this.port);
                IPEndPoint iep = new IPEndPoint(IPAddress.Any, this.port);
                this.server.Bind(iep);
                this.server.Listen(10);

                while (true)
                {
                    this.clientOfServer = this.server.Accept();

                    ThreadPool.QueueUserWorkItem(StartGame, this.clientOfServer);
                }
            }
            catch { }
        }

        //Tạo  máy chủ
        private void CreateHost()
        {
            thListen = new Thread(this.Listen);
            thListen.IsBackground = true;
            thListen.Start();
            this.boardUI1.PlayerSymbol = 'x';//x đi trước
            //this.boardUI1.AllowPlay = true;
            this.btnCreateHost.Enabled = false;
            //this.Host();
        }

        //Giao tiếp với đối thủ
        private void StartGame(object socketclient)
        {
            this.boardUI1.StartGame();
            this.boardUI1.AllowPlay = true;
            this.clientOfServer = socketclient as Socket;
            dataSend = Encoding.Unicode.GetBytes("name:" + Global.Player.Name);
            this.clientOfServer.Send(dataSend);
            MessageBox.Show("Chiến!");
            thStartGame = new Thread((ThreadStart) =>
            {
                bool disConnected = false;
                //Tạo 1 socket kết nối với máy kia
                while (true)//Lấy dữ liệu gửi đến
                {
                    try
                    {
                        this.dataRecive = new byte[1024];
                        clientOfServer.Receive(this.dataRecive);
                        string[] tmp = Encoding.Unicode.GetString(dataRecive).Split(':');
                        //MessageBox.Show(tmp);
                        this.SloveData(tmp);
                    }
                    catch 
                    {
                        disConnected = true;
                        break;
                    }
                }
                if (disConnected)
                {
                    MessageBox.Show("Mất kết nối với đối thủ!");
                    this.Close();
                }
            });
            thStartGame.IsBackground = true;
            thStartGame.Start();
        }

        #endregion

        #region Chế độ tham gia phòng

        private void Connect()
        {
            this.tcpClientConnectToServer = new TcpClient();
            this.tcpClientConnectToServer.Connect(IPAddress.Parse(this.ip), this.port);
            bool disConnected = false;
            this.boardUI1.StartGame();
            this.dataSend = Encoding.Unicode.GetBytes("name:" + Global.Player.Name);
            this.tcpClientConnectToServer.GetStream().Write(dataSend, 0, dataSend.Length);
            while (true)
            {
                try
                {
                    this.dataRecive = new byte[1024];
                    this.tcpClientConnectToServer.GetStream().Read(this.dataRecive, 0, 1024);
                    string[] tmp = Encoding.Unicode.GetString(dataRecive).Split(':');
                    this.SloveData(tmp);
                    //MessageBox.Show(tmp);
                }
                catch
                {
                    disConnected = true;
                    break;
                }
                if (disConnected)
                {
                    MessageBox.Show("Mất kết nối với đối thủ!");
                    this.Close();
                }
            }
        }

        private void ConnectToHost()
        {
            this.mode = Mode.Client;
            this.boardUI1.PlayerSymbol = 'o';//o đi sau
            this.boardUI1.AllowPlay = false;
            this.btnConnect.Enabled = false;
            thKetNoiDenServer = new Thread(Connect);
            thKetNoiDenServer.IsBackground = true;//Khi thoát sẽ đóng luồng lại
            thKetNoiDenServer.Start();
        }

        #endregion

        #region Sự kiện

        private void btnCreateHost_Click(object sender, EventArgs e)
        {
            this.CreateHost();
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            this.ConnectToHost();
        }

        private void boardUI1_MouseClick(object sender, MouseEventArgs e)
        {
            if (this.boardUI1.AllowPlay)//nếu được chơi thì mới gửi dũ liệu
            {
                try
                {
                    this.boardUI1.AllowPlay = false;//Chơi xog  thì nghỉ
                    string data = "Board:" + e.X + ":" + e.Y + ":" + this.boardUI1.PlayerSymbol;//Gửi tạo độ cho đối thủ
                    this.dataSend = Encoding.Unicode.GetBytes(data);
                    if (this.mode == Mode.Client)
                        this.tcpClientConnectToServer.GetStream().Write(dataSend, 0, dataSend.Length);
                    else
                        this.clientOfServer.Send(this.dataSend);
                }
                catch
                {
                    MessageBox.Show("Mất kết nối với đối thủ!");
                    this.Close();
                }
            }
        }

        private void boardUI1_MouseClick_Ai(object sender, MouseEventArgs e)
        {
            //this.boardUI1.AllowPlay = false;
        }

        private void boardUI1_HaveWinner()
        {
            this.Close();
        }

        private void StopThread(Thread th)
        {
            if (th != null && th.ThreadState != ThreadState.Stopped)
                th.Abort();
        }

        private void frmPlay_FormClosed(object sender, FormClosedEventArgs e)
        {
            //thKetNoiDenServer, thListen, thStartGame;
            //this.StopThread(this.thStartGame);
            //this.StopThread(this.thListen);
            //this.StopThread(this.thKetNoiDenServer);
            try
            {
                string data = "Data:" + "Close";
                this.dataSend = Encoding.Unicode.GetBytes(data);
                if (this.mode == Mode.Client)
                    this.tcpClientConnectToServer.GetStream().Write(dataSend, 0, dataSend.Length);
                else
                    this.clientOfServer.Send(this.dataSend);
            }
            catch
            {
            }
            this.Dispose();
        }

        #endregion
    }
}
